//
// Copyright (c) 2024 BPer
//

#include <bperrtc/BPerBandwidth.h>
#include <bperrtc/BPerRtcStats.h>


void bPer_bandwidth_updateEstimate(int64_t now_ms) {

}

//by lost rtp packet rate
int32_t bPer_bandwidth_check(BPerBandwidthSession *bw, BPerRtcStats *stats, BPerStreamConfig *streamconfig, uint32_t ssrc) {

    int32_t err = BPer_Ok;
    bw->lostRate = 0;

    if (stats->recvStats.video.fractionLost < kDefaultHighLossThreshold && bw->preLostRateState == BPerLowLostRate)
        return BPer_Ok;

    if (stats->recvStats.video.fractionLost > kDefaultHighLossThreshold) {
        bw->hightLostCount++;
        bw->lowLostCount = 0;
        if (bw->hightLostCount >= BPer_LostRate_defaultCount) {
            bw->lostRate = stats->recvStats.video.fractionLost;
            bw->lostRateState = BPerHighLostRate;
        }
    } else {
        bw->lowLostCount++;
        bw->hightLostCount = 0;
        if (bw->hightLostCount >= BPer_LostRate_defaultCount) {
            bw->lostRate = stats->recvStats.video.fractionLost;
            bw->lostRateState = BPerLowLostRate;
        }
    }


    if (bw->preLostRateState == bw->lostRateState) return BPer_Ok;

    //hight lost rate
    if (bw->lostRateState == BPerHighLostRate) {

        if (streamconfig->rtcCallback.sendRequest) {
            streamconfig->rtcCallback.sendRequest(streamconfig->rtcCallback.context, streamconfig->uid, ssrc,
                                                  BPer_Req_HighLostPacketRate);
        }


    } else if (bw->lostRateState == BPerLowLostRate) {            //low lost rate
        if (streamconfig->rtcCallback.sendRequest)
            streamconfig->rtcCallback.sendRequest(streamconfig->rtcCallback.context, streamconfig->uid, ssrc,
                                                  BPer_Req_LowLostPacketRate);

    }

    bw->preLostRateState = bw->lostRateState;

    return err;
}

int32_t bPer_bandwidth_checkByTwcc(BPerBandwidthSession *bw, BPerTwccSession *twcc) {
    int32_t err = BPer_Ok;
    return err;
}

int32_t bPer_bandwidth_estimate(BPerBandwidthSession *bw, BPerTwccSession *twcc) {
    return BPer_Ok;
}

void bPer_create_bandwidth(BPerBandwidth *bw) {
    bw->estimate = bPer_bandwidth_estimate;
    bw->checkByTwcc = bPer_bandwidth_checkByTwcc;
    bw->checkBandWidth = bPer_bandwidth_check;
}

void bPer_destroy_bandwidth(BPerBandwidth *bw) {

}

